package com.sxintelbox.serialPort;

import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class UGComBean {
    public int start; // 帧头 ---1byte
    public int address; //从机地址 即某块锁板单片机的编号 ---1byte
    public int command; //指令代码：查询 0x80 0x8A 开锁 ---1byte
    public int paramlen; //参数长度 ---2byte
    public byte[] param; //指令参数内容
    public int check; // 校验和 ---1byte
    public static final String TAG = "COM_BEAN";

    public UGComBean(byte[] data) {
        DataInputStream ds = new DataInputStream(new ByteArrayInputStream(data));
        try {
            this.start = ds.readUnsignedByte();
            this.address = ds.readUnsignedByte();
            this.command = ds.readUnsignedByte();
            this.paramlen = data.length - 4;
            this.param = new byte[data.length - 4];
            ds.read(this.param, 0, this.paramlen);
            this.check = ds.readUnsignedByte();
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            e.printStackTrace();
        }
    }


    // 发送数据 自动计算校验位和数据长度
    public UGComBean(int start, int address, int command, byte[] param) {
        this.start = start;
        this.address = address;
        this.command = command;
        this.param = param;
        this.paramlen = param.length;
    }

    //打包数据帧
    public byte[] pack() {
        try {
            ByteArrayOutputStream bin = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(bin);
            out.writeByte(this.start);
            out.writeByte(this.address);
            out.write(this.param);
            out.writeByte(this.command);
            out.write(toByteArray(getBCC(bin.toByteArray())));
            return bin.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        }
    }

    private static String getBCC(byte[] data) {
        String ret = "";
        byte BCC[] = new byte[1];
        for (int i = 0; i < data.length; i++) {
            BCC[0] = (byte) (BCC[0] ^ data[i]);
        }
        String hex = Integer.toHexString(BCC[0] & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        ret += hex.toUpperCase();
        return ret;
    }

    public static byte[] toByteArray(String hexString) {
        hexString = hexString.toLowerCase();
        final byte[] byteArray = new byte[hexString.length() / 2];
        int k = 0;
        for (int i = 0; i < byteArray.length; i++) {
            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
            byteArray[i] = (byte) (high << 4 | low);
            k += 2;
        }
        return byteArray;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) { // 使用String的format方法进行转换
            buf.append(String.format("%02X ", b & 0xff));
        }
        return buf.toString();
    }

    public static byte xorComputeResult(int[] intgResult) {
        for (int i = 1; i < intgResult.length; i++) {
            intgResult[i] = (intgResult[i - 1] ^ intgResult[i]);
            if (i == intgResult.length - 1) {
                return ((byte) intgResult[i]);
            }
        }
        return 0x00;
    }

    /**
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序。
     *
     * @param ary
     *            byte数组
     * @param offset
     *            从数组的第offset位开始
     * @return int数值
     */
    public static int bytesToInt(byte[] ary, int offset) {
        int value;
        value = (int) ((ary[offset]&0xFF)
                | ((ary[offset+1]<<8) & 0xFF00)
                | ((ary[offset+2]<<16)& 0xFF0000)
                | ((ary[offset+3]<<24) & 0xFF000000));
        return value;
    }

    public static int CRC8(byte[] data) {
        int len = data.length;
        if (len > 0) {
            short crc = 0x0000;
            for (int i = 0; i < len; i++) {
                crc += data[i];
            }

            return crc & 0x00FF;
        }
        return 0;
    }

    public DataInputStream getParam() {
        return new DataInputStream(new ByteArrayInputStream(this.param));
//        return new DataInputStream(this.param);
    }
}
